package service.util;

import common.consts.Consts;
import common.consts.Gender;
import common.consts.YesNo;
import domain.ApplyCondition;
import domain.UserProfile;
import service.ServiceResponse;

/**
 * Created by aceyin on 15/6/29.
 */
public class ConditionMatcher {

    public static final boolean check(UserProfile profile, ApplyCondition condition) {
        if (!experienceMatches(profile, condition)) {
            return false;
        }
        if (!ageMatches(profile, condition)) {
            return false;
        }

        if (!genderMatches(profile, condition)) {
            return false;
        }

        if (!heightMatches(profile, condition)) {
            return false;
        }
        return true;
    }

    /**
     * 检查某个用户是否符合一个工作的要求。
     *
     * @param profile
     * @param condition
     * @return
     */
    public static final ServiceResponse checkWithResponse(UserProfile profile, ApplyCondition condition) {
        if (!experienceMatches(profile, condition)) {
            return ServiceResponse.fail(Consts.i18nKey.APPLY_FAILED_DUE_TO_EXPERIENCE_NOT_MATCH);
        }
        if (!ageMatches(profile, condition)) {
            return ServiceResponse.fail(Consts.i18nKey.APPLY_FAILED_DUE_TO_AGE_NOT_MATCH);
        }

        if (!genderMatches(profile, condition)) {
            return ServiceResponse.fail(Consts.i18nKey.APPLY_FAILED_DUE_TO_GENDER_NOT_MATCH);
        }

        if (!heightMatches(profile, condition)) {
            return ServiceResponse.fail(Consts.i18nKey.APPLY_FAILED_DUE_TO_HEIGHT_NOT_MATCH);
        }
        return ServiceResponse.success();
    }

    private static boolean heightMatches(UserProfile profile, ApplyCondition condition) {
        Integer requiredHeight = condition.getHeight();
        if (requiredHeight == null || requiredHeight.intValue() <= 0) {
            return true;
        }
        Integer userHeight = profile.getHeight();
        if (userHeight == null || userHeight.intValue() <= 0) {
            return false;
        }
        return userHeight >= requiredHeight;
    }

    private static boolean genderMatches(UserProfile profile, ApplyCondition condition) {
        String requiredGender = condition.getGender();
        if (Gender.isInvalid(requiredGender)) {
            return true;
        }
        String userGender = profile.getGender();
        return requiredGender.equalsIgnoreCase(userGender);
    }

    private static boolean ageMatches(UserProfile profile, ApplyCondition condition) {
        Integer minAge = condition.getMinAge();
        Integer maxAge = condition.getMaxAge();
        if ((minAge == null || minAge.intValue() <= 0) && (maxAge == null || maxAge.intValue() <= 0)) {
            return true;
        }
        Integer age = profile.getAge();
        if (age == null || age.intValue() <= 0) {
            return false;
        }

        if (minAge == null) {
            minAge = 0;
        }
        if (maxAge == null) {
            maxAge = 0;
        }
        return age >= minAge && age <= maxAge;
    }

    /**
     * @param profile
     * @param condition
     * @return
     */
    private static boolean experienceMatches(UserProfile profile, ApplyCondition condition) {
        Character requiredExperience = condition.getWorkExperience();
        if (requiredExperience == null || YesNo.isNo(requiredExperience)) {
            return true;
        }
        // TODO: add logic to check experience
        return false;
    }
}
